﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ExpressionEvaluator.Anonymous
{
    internal class AnonymousArgumentProcessor
    {
        private AnonymousArgument[] _Arguments;
        /// <summary>
        /// Initializes a new instance of the <see cref="AnonymousArgumentProcessor"/> class.
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        public AnonymousArgumentProcessor(params string[] arguments)
        {
            _Arguments = arguments.Select(item => new AnonymousArgument(item)).ToArray();
        }

        /// <summary>
        /// Gets the generic parameters names.
        /// </summary>
        /// <returns>Generic parameter names.</returns>
        public string[] GetGenericParametersNames()
        {
            return _Arguments.Select(item => item.GenericArgumentName).ToArray();
        }

        /// <summary>
        /// Gets the <see cref="ExpressionEvaluator.Anonymous.AnonymousArgument"/> at the specified index.
        /// </summary>
        /// <value>Anonymous argument at the specified index.</value>
        public AnonymousArgument this[int index]
        {
            get
            {
                return _Arguments[index];
            }
        }

        /// <summary>
        /// Assigns the generic parameters.
        /// </summary>
        /// <param name="genericType">The generic type array.</param>
        internal void AssignGenericParameters(System.Reflection.Emit.GenericTypeParameterBuilder[] genericTypes)
        {
            for (int i = 0; i < _Arguments.Length; i++)
            {
                _Arguments[i].AssignGeneratedType(genericTypes[i]);
            }
        }

        /// <summary>
        /// Assigns the fields.
        /// </summary>
        /// <param name="assignFunction">The assign function.</param>
        internal void AssignFields(Func<AnonymousArgument, System.Reflection.Emit.FieldBuilder> assignFunction)
        {
            foreach (var item in _Arguments)
            {
                item.AssignField(assignFunction(item));
            }
        }

        /// <summary>
        /// Gets the generics parameters.
        /// </summary>
        /// <returns>Generics parameters of arguments.</returns>
        internal Type[] GetGenericsParameters()
        {
            return _Arguments.Select(item => item.GeneratedType).ToArray();
        }
    }
}
